package com.ruoyi.teaching.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.li.work.domain.vo.WorkDeptUserVO;
import com.ruoyi.li.work.mapper.SysDeptMapper;
import com.ruoyi.li.work.mapper.SysUserMapper;
import com.ruoyi.teaching.domain.*;
import com.ruoyi.teaching.domain.vo.*;
import com.ruoyi.teaching.mapper.*;

import com.ruoyi.teaching.service.PlatformEExamService;
import com.ruoyi.teaching.utils.UniversalUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 王旭
 * @since 2024-06-15
 */
@Service
public class PlatformEExamServiceImpl extends ServiceImpl<PlatformEExamMapper, PlatformEExam> implements PlatformEExamService {

    @Autowired
    private PlatformEExamMapper platformEExamMapper;

    @Autowired
    private PlatformCCourseMapper platformCCourseMapper;

    @Autowired
    private PlatformCCourseDeptMapper platformCCourseDeptMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private PlatformEExamQuestionMapper platformEExamQuestionMapper;

    @Autowired
    private PlatformQQuestionMapper platformQQuestionMapper;

    @Autowired
    private PlatformQKnowledgeMapper platformQKnowledgeMapper;

    @Autowired
    private PlatformEScoreMapper platformEScoreMapper;

    @Autowired
    private SysDeptMapper deptMapper;

    @Override
    public AjaxResult selectPlatformEExamList(Integer pageNum, Integer pageSize, String examName, Integer examCourse, Integer deptId) {
        Page<PlatformEExam> platformEExamPage = new Page<>(pageNum, pageSize);
        QueryWrapper<PlatformEExam> platformEExamQueryWrapper = new QueryWrapper<>();

        // 获取当前用户ID
        int userId = SecurityUtils.getUserId().intValue();
        platformEExamQueryWrapper.eq("create_id", userId);

        // 如果考试名称不为空，则进行模糊查询
        if (examName != null && !examName.equals("")) {
            platformEExamQueryWrapper.like("exam_name", examName);
        }

        // 如果课程ID不为空，则进行精确查询
        if (examCourse != null) {
            platformEExamQueryWrapper.eq("exam_course", examCourse);
        }

        // 根据 id 字段倒序排序
        platformEExamQueryWrapper.orderByDesc("id");

        // 分页查询考试列表
        Page<PlatformEExam> examPage = platformEExamMapper.selectPage(platformEExamPage, platformEExamQueryWrapper);
        List<PlatformEExam> records = examPage.getRecords();

        // 构造返回结果
        Page<PlatformEExamVO> platformEExamVOPage = new Page<>(pageNum, pageSize);
        List<PlatformEExamVO> platformEExamVOS = new ArrayList<>();

        for (PlatformEExam record : records) {
            PlatformEExamVO platformEExamVO = new PlatformEExamVO();
            BeanUtils.copyProperties(record, platformEExamVO);
            Integer[] deptIds = platformCCourseDeptMapper.selectByCourseId(record.getExamCourse());
            platformEExamVO.setExamDept(deptIds);
            platformEExamVOS.add(platformEExamVO);
        }

        //根据班级ID过滤课程
        if (deptId != null) {
            if (deptId == 0) {
                // 获取老师所关联的班级列表
                Long uid = SecurityUtils.getUserId();
                String deptIds = sysUserMapper.selectUserById(uid).getClassId();
                List<String> stringClassIds = StringUtils.str2List(deptIds, ",", true, true);
                // 获取班级信息
                Integer[] sysDepts = new Integer[stringClassIds.size()];
                for (int i = 0; i < stringClassIds.size(); i++) {
                    long l = Long.parseLong(stringClassIds.get(i));
                    SysDept sysDept = deptMapper.selectDeptById(l);
                    if (sysDept != null) {
                        int classId = sysDept.getDeptId().intValue();
                        sysDepts[i] = classId;
                    }
                }
                platformEExamVOS.removeIf(platformEExamVO -> !Arrays.equals(platformEExamVO.getExamDept(), sysDepts));
            } else {
                Integer[] deptId1 = {deptId};
                platformEExamVOS.removeIf(platformEExamVO -> !Arrays.equals(platformEExamVO.getExamDept(), deptId1));
            }
        }

        // 设置分页数据
        BeanUtils.copyProperties(examPage, platformEExamVOPage);
        platformEExamVOPage.setRecords(platformEExamVOS);

        return new AjaxResult(HttpStatus.SUCCESS, "查询成功", platformEExamVOPage);
    }


    @Override
    public AjaxResult selectPlatformEExamById(Long id) {
        // 创建返回对象
        PlatformEExamOutVO platformEExamOutVO = new PlatformEExamOutVO();

        // 查询考试信息并复制到返回对象
        PlatformEExam platformEExam = platformEExamMapper.selectById(id);
        if (platformEExam == null) {
            return new AjaxResult(HttpStatus.ERROR, "未找到相关考试信息");
        }
        BeanUtils.copyProperties(platformEExam, platformEExamOutVO);

        // 查询相关的考试题目信息
        QueryWrapper<PlatformEExamQuestion> platformEExamQuestionQueryWrapper = new QueryWrapper<>();
        platformEExamQuestionQueryWrapper.eq("exam_id", id);
        List<PlatformEExamQuestion> platformEExamQuestions = platformEExamQuestionMapper.selectList(platformEExamQuestionQueryWrapper);

        // 创建题目输出对象列表
        List<QuestionOutVO> questionOutVOS = new ArrayList<>();
        /**  以下注释掉的代码为查询随机出题时返回的总信息 */
//        List<PlatformEExamQuestionInVO> platformEExamQuestionInVOS = new ArrayList<>();

//        // 各类型题目分类存储
//        Map<Integer, List<PlatformQQuestion>> questionTypeMap = new HashMap<>();
//        Map<Integer, Integer> questionValueMap = new HashMap<>();
//        Set<Integer> knowledgeIds = new HashSet<>();
//
//        // 初始化题目类型的映射
//        for (int i = 0; i <= 4; i++) {
//            questionTypeMap.put(i, new ArrayList<>());
//        }

        // 处理考试题目信息
        for (PlatformEExamQuestion platformEExamQuestion : platformEExamQuestions) {
            PlatformQQuestion platformQQuestion = platformQQuestionMapper.selectById(platformEExamQuestion.getQuestionId());
            if (platformQQuestion != null) {
//                if (platformEExamOutVO.getExamWay() == 0) {
                    // 复制题目信息到输出对象
                    PlatformQQuestionVO platformQQuestionVO = UniversalUtil.stringToArray(platformQQuestion);
                    QuestionOutVO questionOutVO = new QuestionOutVO();
                    BeanUtils.copyProperties(platformQQuestionVO, questionOutVO);
                    questionOutVO.setQuestionValue(platformEExamQuestion.getQuestionValue());
                    questionOutVOS.add(questionOutVO);
//                } else if (platformEExamOutVO.getExamWay() == 1) {
//                    // 按题目类型分类存储
//                    knowledgeIds.add(platformQQuestion.getKnowledgeId());
//                    int questionType = platformQQuestion.getQuestionType();
//                    questionTypeMap.get(questionType).add(platformQQuestion);
//                    questionValueMap.put(questionType, platformEExamQuestion.getQuestionValue());
//                }
            }
        }

        // 设置考试题目信息到返回对象
//        if (platformEExamOutVO.getExamWay() == 1) {
//            List<String> knowledgeNames = new ArrayList<>();
//            // 查找知识点名字
//            for (Integer knowledgeId : knowledgeIds) {
//                PlatformQKnowledge platformQKnowledge = platformQKnowledgeMapper.selectById(knowledgeId);
//                knowledgeNames.add(platformQKnowledge.getKnowledgeName());
//            }
//            platformEExamOutVO.setKnowledgeNames(knowledgeNames);

//            // 生成随机题目信息
//            for (int i = 0; i <= 4; i++) {
//                PlatformEExamQuestionInVO platformEExamQuestionInVO = new PlatformEExamQuestionInVO();
//                platformEExamQuestionInVO.setQuestionType(i);
//                platformEExamQuestionInVO.setQuestionValue(questionValueMap.getOrDefault(i, 0));
//                platformEExamQuestionInVO.setQuestionNumber(questionTypeMap.get(i).size());
//                platformEExamQuestionInVOS.add(platformEExamQuestionInVO);
//            }
//            platformEExamOutVO.setQuestionsRandom(platformEExamQuestionInVOS);
//        }else {
            platformEExamOutVO.setPlatformEExamQuestions(questionOutVOS);
//        }

        // 返回成功结果
        return new AjaxResult(HttpStatus.SUCCESS, "查询成功", platformEExamOutVO);
    }


    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public AjaxResult insertPlatformEExam(PlatformEExamInVO platformEExamVO) {
        PlatformEExam platformEExam = new PlatformEExam();
        BeanUtils.copyProperties(platformEExamVO, platformEExam);

        //获取并设置发布人信息
        UniversalCreateUpdate createUpdate = UniversalUtil.getCreateUpdate(sysUserMapper);
        platformEExam.setCreateBy(createUpdate.getName());
        platformEExam.setCreateId(createUpdate.getId());
        platformEExam.setCreateTime(DateUtils.getNowDate());

        int insert = platformEExamMapper.insert(platformEExam);
        if (insert == 0) {
            throw new RuntimeException("新增失败");
        }

        // 获取考试相关信息
        Integer examId = platformEExam.getId();
        String examName = platformEExam.getExamName();

        // 拿到题目信息
        List<PlatformEExamQuestionInVO> platformEExamQuestions = platformEExamVO.getPlatformEExamQuestions();

        // 通过查询该门备课下的班级将试卷发给各个同学
        Integer examCourseId = platformEExamVO.getExamCourse();
        Integer id = platformCCourseMapper.selectById(examCourseId).getId();
        Integer[] deptIds = platformCCourseDeptMapper.selectByCourseId(id);

        // 手动出题
        if (platformEExamVO.getExamWay() == 0) {
            handleManualExam(platformEExamQuestions, examId, examName, deptIds);
        }
        // 自动出题
        else if (platformEExamVO.getExamWay() == 1) {
            handleAutoExam(platformEExamQuestions, examId, examName, deptIds,platformEExamVO.getKnowledgeNames());
        }
        // 出题方式错误
        else {
            throw new RuntimeException("出题方式有误");
        }

        return new AjaxResult(HttpStatus.SUCCESS, "新增成功");
    }

    private void handleManualExam(List<PlatformEExamQuestionInVO> platformEExamQuestions, Integer examId, String examName, Integer[] deptIds) {
        List<ScoreInfoInVO> scoreInfoInVOS = new ArrayList<>();
        // 存入试卷题库中间表
        for (PlatformEExamQuestionInVO platformEExamQuestionInVO : platformEExamQuestions) {
            PlatformEExamQuestion platformEExamQuestion = new PlatformEExamQuestion();
            BeanUtils.copyProperties(platformEExamQuestionInVO, platformEExamQuestion);
            platformEExamQuestion.setExamId(examId);
            platformEExamQuestionMapper.insert(platformEExamQuestion);

            // 组合试卷信息
            ScoreInfoInVO scoreInfoVO = new ScoreInfoInVO();
            scoreInfoVO.setId(platformEExamQuestionInVO.getQuestionId());
            scoreInfoVO.setQuestionValue(platformEExamQuestion.getQuestionValue());
            scoreInfoInVOS.add(scoreInfoVO);
        }
        distributeExamToStudents(scoreInfoInVOS, examId, examName, deptIds);
    }

    private void handleAutoExam(List<PlatformEExamQuestionInVO> platformEExamQuestions, Integer examId, String examName, Integer[] deptIds,List<String> knowledgeNames) {
        List<ScoreInfoInVO> scoreInfoInVOS = new ArrayList<>();
        List<Integer> kIds = new ArrayList<>();
        if(CollectionUtils.isEmpty(knowledgeNames)){    //  查全部
            Long userId = SecurityUtils.getUserId();
            Long deptId = sysUserMapper.selectUserById(userId).getMajorId();
            String specialtyName = deptMapper.selectDeptById(deptId).getDeptName();

            //查询所有学校当前专业下的知识点
            Long[] deptIdss = deptMapper.selectDeptIdByName(specialtyName);
            List<PlatformQKnowledgeVO> platformQKnowledges = platformQKnowledgeMapper.selectKnowledgeListBySpecialtyId(deptIdss);
            for (PlatformQKnowledgeVO platformQKnowledge : platformQKnowledges) {
                kIds.add(platformQKnowledge.getId());
            }
        }else {
            for (String knowledgeName : knowledgeNames) {
                List<Integer> knowledgeIds = platformQKnowledgeMapper.selectKnowledgeIdByName(knowledgeName);
                for (Integer knowledgeId : knowledgeIds) {
                    kIds.add(knowledgeId);
                }
            }
        }

        for (PlatformEExamQuestionInVO platformEExamQuestion : platformEExamQuestions) {
            Integer questionNumber = platformEExamQuestion.getQuestionNumber();
            Integer questionType = platformEExamQuestion.getQuestionType();
            List<PlatformQQuestion> questions = platformQQuestionMapper.random(questionType,kIds, questionNumber);

            for (PlatformQQuestion question : questions) {
                PlatformEExamQuestion platformEExamQuestion1 = new PlatformEExamQuestion();
                platformEExamQuestion1.setQuestionId(question.getId());
                platformEExamQuestion1.setQuestionValue(platformEExamQuestion.getQuestionValue());
                platformEExamQuestion1.setExamId(examId);
                platformEExamQuestionMapper.insert(platformEExamQuestion1);

                // 组合试卷信息
                ScoreInfoInVO scoreInfoVO = new ScoreInfoInVO();
                scoreInfoVO.setId(question.getId());
                scoreInfoVO.setQuestionValue(platformEExamQuestion.getQuestionValue());
                scoreInfoInVOS.add(scoreInfoVO);
            }
        }
        distributeExamToStudents(scoreInfoInVOS, examId, examName, deptIds);
    }

    private void distributeExamToStudents(List<ScoreInfoInVO> scoreInfoInVOS, Integer examId, String examName, Integer[] deptIds) {
        for (Integer deptId : deptIds) {
            // 根据部门的id查询到用户信息
            String deptIdLong = String.valueOf(deptId);
            List<SysUser> studentsOld = sysUserMapper.selectUserByDeptId(deptIdLong);
            List<SysUser> students = new ArrayList<>();
            studentsOld.stream().filter(distinctByKey(SysUser::getUserId)) //filter保留true的值
                    .forEach(students::add);
            for (SysUser student : students) {
                int studentId = student.getUserId().intValue();
                PlatformEScore platformEScore = new PlatformEScore();
                platformEScore.setExamId(examId);
                platformEScore.setExamName(examName);
                platformEScore.setExamStatus(0);
                platformEScore.setStudentId(studentId);
                platformEScore.setDeptId(deptId);
                platformEScore.setVettingStatus(0);
                platformEScore.setScoreInfo(JSON.toJSONString(scoreInfoInVOS, SerializerFeature.WriteMapNullValue));
                //获取并设置发布人信息
                UniversalCreateUpdate createUpdate = UniversalUtil.getCreateUpdate(sysUserMapper);
                platformEScore.setCreateBy(createUpdate.getName());
                platformEScore.setCreateId(createUpdate.getId());
                platformEScore.setCreateTime(DateUtils.getNowDate());
                // 保存 PlatformEScore
                platformEScoreMapper.insert(platformEScore);
            }
        }
    }

    static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object,Boolean> seen = new ConcurrentHashMap<>();
        //putIfAbsent方法添加键值对，如果map集合中没有该key对应的值，则直接添加，并返回null，如果已经存在对应的值，则依旧为原来的值。
        //如果返回null表示添加数据成功(不重复)，不重复(null==null :TRUE)
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }


    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public AjaxResult deletePlatformEExamByIds(Long[] ids) {
        // 记录成功删除的考试数量
        int successCount = 0;

        for (Long id : ids) {
            // 删除考试记录
            int deleteCount = platformEExamMapper.deleteById(id);
            if (deleteCount > 0) {
                successCount++;
                // 删除考试和题目的关联
                platformEExamQuestionMapper.deleteByExamId(id);
                // 删除考试成绩
                platformEScoreMapper.deleteByExamId(id);
            }
        }

        // 检查是否所有考试都成功删除
        if (successCount == ids.length) {
            return new AjaxResult(HttpStatus.SUCCESS, "删除成功");
        } else {
            throw new RuntimeException("删除失败");
        }
    }
}
